package nmp.remote;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import nmp.gui.CGroupListAdapter;
import nmp.gui.CWifiConfigDlg;
import nmp.lib.CNmpDevice;
import nmp.lib.CNmpDongle;
import nmp.lib.CNmpCmd.NmpCmdBase;
import nmp.lib.CNmpCmd.NmpCmdDeviceInfo;
import nmp.lib.CNmpCmd.NmpCmdIdentifyInfo;
import nmp.lib.CNmpCmd.NmpCmdIsConnected;
import nmp.lib.CNmpCmd.NmpCmdWifiList;
import nmp.lib.CNmpCmd.NmpWifiInfo;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class NmpDeviceStatus extends Activity  {

	private enum CONTROL_STATE {
		NONE,
		READY,
		GET_DEVICE_INFO,
		SET_DEVICE_WIFICONFIG_CONFIRM,
		SET_DEVICE_WIFICONFIG_SETTING,
		SET_DEVICE_WIFICONFIG_RESTART,
		CLOSE
	};
	
	private NmpCmdDeviceInfo mDeviceInfo;
	private CNmpDongle mNmpDevice = null;
	private Context mContext;
	
	private ListView mListView;
	private CGroupListAdapter mGroupAdapter;
	private ProgressDialog mGetDeviceInfoBusyDialog = null;
	private ProgressDialog mSetWifiConfigBusyDialog = null;
	private CONTROL_STATE mState = CONTROL_STATE.NONE;
	
	private Handler mHandlerTime;
    private Runnable mTimerRun;
    
    private String mStrCancel;
    
	@Override
	public void onCreate(Bundle savedInstanceState) 
	{
		Log.d(this.toString(),"onCreate start !!!!");
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
	    setContentView(R.layout.device_status);
	    mState = CONTROL_STATE.NONE;
	    mContext = this;
	    mListView = (ListView) findViewById(R.id.listViewDeviceInfo);
	    
		mGetDeviceInfoBusyDialog = new ProgressDialog(this);  
		mGetDeviceInfoBusyDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
		mGetDeviceInfoBusyDialog.setTitle(this.getString(R.string.get_device_info));
		mGetDeviceInfoBusyDialog.setIndeterminate(false);
		mGetDeviceInfoBusyDialog.setCancelable(true);
		
		mStrCancel = this.getResources().getString(R.string.cancel);
		
		mGetDeviceInfoBusyDialog.setButton(ProgressDialog.BUTTON_NEUTRAL,mStrCancel,new DialogInterface.OnClickListener(){  
			  
            public void onClick(DialogInterface dialog, int which) {  
            	UpdateDeviceInfoList(null);                
                SetToState(CONTROL_STATE.READY);
                dialog.cancel();  
            } 
        });
		
		mSetWifiConfigBusyDialog = new ProgressDialog(this);  
		mSetWifiConfigBusyDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
		mSetWifiConfigBusyDialog.setTitle(this.getString(R.string.set_wifi_configuration));
		mSetWifiConfigBusyDialog.setIndeterminate(false);
		mSetWifiConfigBusyDialog.setCancelable(true);
		mSetWifiConfigBusyDialog.setButton(ProgressDialog.BUTTON_NEUTRAL,mStrCancel,new DialogInterface.OnClickListener(){  
			  
            public void onClick(DialogInterface dialog, int which) {     
            	SetToState(CONTROL_STATE.READY);
            } 
        });		
		
		Log.d(this.toString(),"onCreate end");
	}
	
	@Override
	protected void onDestroy() {
		Log.d(this.toString(),"onDestroy start");
		// TODO Auto-generated method stub
		super.onDestroy();
		Log.d(this.toString(),"onDestroy stop");
	}
	@Override
	protected void onPause() {
		Log.d(this.toString(),"onPause start");
		// TODO Auto-generated method stub
		SetToState(CONTROL_STATE.CLOSE);	
		NmpDeviceClose();
		super.onPause();
		Log.d(this.toString(),"onPause stop");
	}
	@Override
	protected void onPostCreate(Bundle savedInstanceState) {
		Log.d(this.toString(),"onPostCreate start");
		// TODO Auto-generated method stub
		super.onPostCreate(savedInstanceState);
		Log.d(this.toString(),"onPostCreate stop");
	}
	@Override
	protected void onPostResume() {
		Log.d(this.toString(),"onPostResume start");
		// TODO Auto-generated method stub
		super.onPostResume();
		Log.d(this.toString(),"onPostResume stop");
	}
	@Override
	protected void onRestart() {
		Log.d(this.toString(),"onRestart start");
		// TODO Auto-generated method stub
		super.onRestart();
		Log.d(this.toString(),"onRestart stop");
	}
	@Override
	protected void onResume() {
		Log.d(this.toString(),"onResume start");
		// TODO Auto-generated method stub
		super.onResume();
	
		// unit test here
		/*
		NmpCmdDeviceInfo info = new NmpCmdDeviceInfo();
		info.ssid = "walace_ssid";
		info.password = "52walace";
		info.name = "walace donge name";
		info.mac = "12341234";
		info.firmware_majon = 1;
		info.firmware_minor = 10;		
		UpdateDeviceInfoList(info);
		*/
		SetToState(CONTROL_STATE.NONE);	
		NmpDeviceOpen();			
		Log.d(this.toString(),"onResume stop");
	}
	@Override
	protected void onStart() {
		Log.d(this.toString(),"onStart start");
		// TODO Auto-generated method stub

		super.onStart();
		Log.d(this.toString(),"onStart stop");
	}
	@Override
	protected void onStop() {
		Log.d(this.toString(),"onStop start");
		// TODO Auto-generated method stub

		super.onStop();
		Log.d(this.toString(),"onStop stop");
	}
	
	private void ConnectResultHandle(boolean connect) {
		
		if(IsState(CONTROL_STATE.NONE)) { 
			if(connect){
				GetDeviceInfo();
			} else {
				UpdateDeviceInfoList(null);
				mGetDeviceInfoBusyDialog.dismiss();
				SetToState(CONTROL_STATE.NONE);
			}				
		} else if(IsState(CONTROL_STATE.GET_DEVICE_INFO)) {
			if(connect) {
				
			} else {
            	UpdateDeviceInfoList(null);
            	mGetDeviceInfoBusyDialog.dismiss();
                SetToState(CONTROL_STATE.NONE);				
			}
		} else if(IsState(CONTROL_STATE.SET_DEVICE_WIFICONFIG_RESTART)) {
			mSetWifiConfigBusyDialog.dismiss();
			if(connect){    			
    			SetToState(CONTROL_STATE.READY);
			}else{
				mNmpDevice.ReConnect(3000);
			}
		} else {
	
		}
	}
	 
	private void GetDeviceInfo(){
		
		if(IsState(CONTROL_STATE.NONE)) {
			NmpDeviceOpen();
		} else if (IsState(CONTROL_STATE.READY)) {
			SetToState(CONTROL_STATE.GET_DEVICE_INFO);
			mGetDeviceInfoBusyDialog.show();  			
			mNmpDevice.SendDeviceInfoCmd();
		}
	}
	 

    private void NmpDeviceOpen() {
    	
    	NmpDeviceClose();
    	
		mNmpDevice = new CNmpDongle(this)
		{			
			public void DeviceStatus(int status){
				
				switch(status) {
					case CNmpDevice.DEVICE_STATUS_DISCONNECT:
						ConnectResultHandle(false);
						break;
					case CNmpDevice.DEVICE_STATUS_CONNECT:
						ConnectResultHandle(true);
						break;
				}
				
			}
			
			public void GetIdentifyResponse(NmpCmdIdentifyInfo info) {
				
			}
			
			public void GetWifiListResponse(NmpCmdWifiList info) {
			}

			public void GetWifiConnectResponse(NmpCmdBase info) {
				
			}
			
			public void GetWifiDisConnectResponse(NmpCmdBase info) {
				
			}
			
			public void GetDeviceInfoResponse(NmpCmdDeviceInfo info) {		
				if(IsState(CONTROL_STATE.GET_DEVICE_INFO)) {
					UpdateDeviceInfoList(info);
					mGetDeviceInfoBusyDialog.dismiss();
					SetToState(CONTROL_STATE.READY);
				}
			}	

			public void GetWifiConfigResponse(NmpCmdBase info) {
				if(IsState(CONTROL_STATE.SET_DEVICE_WIFICONFIG_SETTING)) {
					// Not Ready, wait device restart and reconnection.
					//NmpDeviceOpen();
					SetToState(CONTROL_STATE.SET_DEVICE_WIFICONFIG_RESTART);					
				}
			}	
			
			public void GetWifiIsConnectedResponse(NmpCmdIsConnected info) {
				
			}	
			
		};   

		if(!mNmpDevice.Connect()) {
			ConnectResultHandle(false);				
		}
    }
    
    private void NmpDeviceClose() {
    	if(mNmpDevice != null) {
    		mNmpDevice.Disconnect();
    		mNmpDevice = null;
    	}    	
    }   
    
    private void GotoGatewaySelectActivie() {
    	Intent intent = new Intent();
		intent.setClass(NmpDeviceStatus.this, NmpGatewaySelect.class);
		startActivity(intent);		 	
    }
    
    private void UpdateDeviceInfoList(NmpCmdDeviceInfo info){
    	
    	mDeviceInfo = info;
    	
		SimpleAdapter listItemAdapter;
		List<Map<String, Object>> listItem;    	
		String str_content;
		Map<String, Object> map;
		String adapter_identify_list[] = new String[] {"ItemTitle", "ItemText","ItemImage"};
		int adapter_resource_list[] = new int[] {R.id.listtextViewTitle,R.id.listtextViewContent,R.id.listimage} ;
		
		mGroupAdapter = new CGroupListAdapter(mContext);
		
		listItem = new ArrayList<Map<String, Object>>();         		
		
    	if(info == null) {

    		map = new HashMap<String, Object>();
    
	        map.put("ItemTitle", getString(R.string.refresh));  
	        map.put("ItemText", getString(R.string.refresh_device_status_again));
	        map.put("ItemImage", R.drawable.refresh);
	        listItem.add(map);
	        
            listItemAdapter = new SimpleAdapter(this,listItem,R.layout.wifilistitem,
            		adapter_identify_list,adapter_resource_list);	  
            
            mGroupAdapter.addSection(this.getString(R.string.no_device_info), listItemAdapter);	
            mListView.setAdapter(mGroupAdapter);
            
            mListView.setOnItemClickListener(new OnItemClickListener() {  
    	    	public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {      	    		
					HashMap<String, String> item = (HashMap<String, String>) mGroupAdapter.getItem(arg2);
					if(item == null) {
						Toast.makeText(getApplicationContext(), "Error!!!", Toast.LENGTH_SHORT).show();
					} else {
	    	    		String ItemTitle = item.get("ItemTitle"); 	    		
	    	    		if(ItemTitle.equals(mContext.getString(R.string.refresh))) {
	    	    			GetDeviceInfo();  
	    	    		}
					}
                }  
            });	 
            
    	} else {   
    		
    		map = new HashMap<String, Object>();
    		
    		map.put("ItemTitle", getString(R.string.gateway_access_point));  
    		
    		if(mNmpDevice == null || mNmpDevice.GetCurrentWifiSSid() == null) {
    			str_content = getString(R.string.unknow) + "\n";    	        
    	        map.put("ItemText", str_content);
    	        map.put("ItemImage", R.drawable.access_point_question);    			
    		} else { 
    			str_content = mNmpDevice.GetCurrentWifiSSid() + "\n";
    	        map.put("ItemText", str_content);
    	        map.put("ItemImage", R.drawable.access_point);    			
    		}
    		

	        listItem.add(map);
	        
    		map = new HashMap<String, Object>();
     		
            str_content = getString(R.string.ssid) +" : " + info.ssid + "\n";
            str_content += getString(R.string.password) +" : " + info.password + 
            		"\n";
            
	        map.put("ItemTitle", getString(R.string.device_access_point));  
	        map.put("ItemText", str_content);
	        map.put("ItemImage", R.drawable.device_access_point);
	        listItem.add(map);
 
            listItemAdapter = new SimpleAdapter(this,listItem,
            		R.layout.wifilistitem, adapter_identify_list, adapter_resource_list); 
            
            mGroupAdapter.addSection(getString(R.string.network_setting), listItemAdapter);	
          
            listItem = new ArrayList<Map<String, Object>>();
            
            str_content = getString(R.string.name) +" : " + info.name + "\n";
            str_content += "MAC : " + info.mac + "\n";
            
	        map = new HashMap<String, Object>();  
	        map.put("ItemTitle", getString(R.string.device_info));  
	        map.put("ItemText", str_content);
	        map.put("ItemImage", R.drawable.device_info);
	        listItem.add(map);
	        
            str_content = getString(R.string.firmware_version) +" : " + info.firmware_majon+"."+info.firmware_minor;
    
	        map = new HashMap<String, Object>();
	        map.put("ItemTitle", getString(R.string.software_info));  
	        map.put("ItemText",  str_content);	  
	        map.put("ItemImage", R.drawable.software_info);
	        listItem.add(map);
	          
            listItemAdapter = new SimpleAdapter(this,listItem,
            		R.layout.wifilistitem, adapter_identify_list, adapter_resource_list); 
            
            mGroupAdapter.addSection(getString(R.string.system_information), listItemAdapter);
            
            mListView.setAdapter(mGroupAdapter);
            
            mListView.setOnItemClickListener(new OnItemClickListener() {  
    	    	public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {      	    		
					HashMap<String, Object> item = (HashMap<String, Object>) mGroupAdapter.getItem(arg2);
					if(item == null) {
						Toast.makeText(getApplicationContext(), "Error!!!", Toast.LENGTH_SHORT).show();
					} else {
	    	    		String ItemTitle = (String) item.get("ItemTitle");
	    	    		
	    	    		if(ItemTitle.equals(getString(R.string.device_access_point)) ) {
	    	    			NmpWifiInfo wifiinfo = new NmpWifiInfo();
	    	    			wifiinfo.ssid = mDeviceInfo.ssid;
	    	    			wifiinfo.password = mDeviceInfo.password;
	    	    			wifiinfo.protect = "NONE";
	    	    			SetToState(CONTROL_STATE.SET_DEVICE_WIFICONFIG_CONFIRM);
	    					CWifiConfigDlg dlg = new CWifiConfigDlg(mContext,(NmpWifiInfo)wifiinfo) {
	    			    		public void Result(NmpWifiInfo wifiinfo) {
	    			    			if(wifiinfo == null) {
	    			    				SetToState(CONTROL_STATE.READY);
	    			    			} else {		    			    				 
	    			    				SetDeviceWifiConfig(wifiinfo);   			    				
	    			    			}
	    			    		}				
	    					};	    					
	    					dlg.SetSSIDEnable(true);
	    					dlg.SetProtectEnable(false);
	    					dlg.show();	    							
	    	    		} else if (ItemTitle.equals(getString(R.string.gateway_access_point))){ 
	    	    			GotoGatewaySelectActivie();
	    	    		}
					}
                }  
            });	            
    	}        
    }     
    
    private void SetDeviceWifiConfig(NmpWifiInfo wifiinfo) {
    	SetToState(CONTROL_STATE.SET_DEVICE_WIFICONFIG_SETTING);	
    	mNmpDevice.SendWifiConfigCmd(wifiinfo.ssid,wifiinfo.protect, wifiinfo.password);	
    	mSetWifiConfigBusyDialog.show();
    }
    
	private void SetToState(CONTROL_STATE state) {
		Log.e(this.toString(),"Current State:" + state);		
		mState = state;
	}    
	
	private boolean IsState(CONTROL_STATE state) {
		Log.e(this.toString(),"Current State:" + mState + " < === > Check State:" + state );			
		return (mState == state);
	}    	
}
